package xyz.labmem.lipx.core.server.core

import cn.hutool.core.date.DateUtil
import io.netty.channel.ChannelInitializer
import io.netty.channel.socket.SocketChannel
import io.netty.handler.codec.LengthFieldBasedFrameDecoder
import io.netty.handler.timeout.IdleStateHandler
import xyz.labmem.common.property.ContextProperty.serverStatusProperty
import xyz.labmem.lipx.core.codec.LabMessageDecoder
import xyz.labmem.lipx.core.codec.LabMessageEncoder
import xyz.labmem.lipx.core.context.AppContext
import xyz.labmem.lipx.core.entity.ServerConfig
import xyz.labmem.lipx.core.net.ServerStatus
import xyz.labmem.lipx.core.net.TcpServer
import xyz.labmem.lipx.core.tool.LogInfo
import xyz.labmem.lipx.core.server.core.handler.LabServerHandler

/**
 * @description: do something
 * @author: ltty
 * @date: 2022/5/30 14:05
 */
class LabNettyPenetrationServer {

    private val nettyServer = TcpServer()

    @Throws(InterruptedException::class)
    fun start(config: ServerConfig) {
        try {
            if (!serverStatusProperty.value()) {
                nettyServer.bind(config.port, object : ChannelInitializer<SocketChannel>() {
                    @Throws(Exception::class)
                    override fun initChannel(ch: SocketChannel) {
                        val serverHandler = LabServerHandler(config)
                        ch.pipeline().addLast(
                            LengthFieldBasedFrameDecoder(Int.MAX_VALUE, 0, 4, 0, 4),
                            LabMessageDecoder(), LabMessageEncoder(),
                            IdleStateHandler(60, 30, 0), serverHandler
                        )
                    }
                }) {
                    serverStatusProperty.value(true)
                    LogInfo.appendLog("LIPX server 启动成功，端口:${config.port}")
//                StaticLog.info("netty启动成功，端口:${config.port}")
                    AppContext.Server.startDate = DateUtil.now()
                }
            } else {
                LogInfo.appendLogError("LIPX server 未关闭，启动失败")
                throw Exception("LIPX server 未关闭，启动失败")
            }
        } catch (e: Exception) {
            println("LIPX server 启动失败")
            LogInfo.appendLogError("LIPX server 启动失败${e.printStackTrace()}")
            close()
            throw Exception("LIPX server 启动失败")
        }
    }

    fun close() {
        nettyServer.close()
        LogInfo.appendLog("LIPX server 已关闭")
    }

    fun restart(config: ServerConfig) {
        close()
        start(config)
    }


}